{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "provenance": []
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "source": [
        "<a href=\"https://colab.research.google.com/drive/1TT5M7GhKLLcJCLjkq4edUWxH_u7kZbMn?usp=sharing\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"></a>"
      ],
      "metadata": {
        "id": "I7C3nWECIHBg"
      }
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "wbJUgBtKIDKB"
      },
      "outputs": [],
      "source": [
        "!pip install -qU google-generativeai"
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "import google.generativeai as genai\n",
        "import re\n",
        "import getpass"
      ],
      "metadata": {
        "id": "ZlwxuT0fH_SM"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "Get Google's Gemini API Key here: https://aistudio.google.com/app/apikey"
      ],
      "metadata": {
        "id": "kSgFQfhfYGYT"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "API_KEY = getpass.getpass(\"Enter your Google API key: \")"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "4m6iOIcSIr9y",
        "outputId": "23cff3a8-28e1-438a-db72-403edb8c7ae6"
      },
      "execution_count": null,
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Enter your Google AI API key: ··········\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# Configure API\n",
        "genai.configure(api_key=API_KEY)"
      ],
      "metadata": {
        "id": "2NVvr2tcIh9R"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "class ReActAgent:\n",
        "    def __init__(self):\n",
        "        self.model = genai.GenerativeModel(\"gemini-2.0-flash\")\n",
        "        self.tools = {}\n",
        "        self.history = []\n",
        "\n",
        "    def add_tool(self, name, func, description):\n",
        "        self.tools[name] = {\"func\": func, \"desc\": description}\n",
        "\n",
        "    def run(self, query, max_steps=5):\n",
        "        print(f\"\\n🎯 Query: {query}\\n\")\n",
        "\n",
        "        for step in range(max_steps):\n",
        "            # Create prompt\n",
        "            tools_desc = \"\\n\".join([f\"{n}: {t['desc']}\" for n, t in self.tools.items()])\n",
        "            prompt = f\"\"\"You are a ReAct agent. Follow this format:\n",
        "            Thought: [your reasoning]\n",
        "            Action: tool_name(param=\"value\")\n",
        "            OR\n",
        "            Final Answer: [final response]\n",
        "\n",
        "            Tools available:\n",
        "            {tools_desc}\n",
        "\n",
        "            Query: {query}\n",
        "\n",
        "            History:\n",
        "            {chr(10).join(self.history)}\n",
        "\n",
        "            Response:\"\"\"\n",
        "\n",
        "            # Get response\n",
        "            response = self.model.generate_content(prompt).text\n",
        "            print(f\"Step {step+1}:\\n{response}\\n\")\n",
        "\n",
        "            # Check if done\n",
        "            if \"Final Answer:\" in response:\n",
        "                return response.split(\"Final Answer:\")[-1].strip()\n",
        "\n",
        "            # Execute action\n",
        "            match = re.search(r'Action:\\s*(\\w+)\\((.*?)\\)', response)\n",
        "            if match:\n",
        "                tool_name = match.group(1)\n",
        "                params_str = match.group(2)\n",
        "\n",
        "                # Parse params\n",
        "                params = {}\n",
        "                for p in re.finditer(r'(\\w+)=[\"\\'](.*?)[\"\\']', params_str):\n",
        "                    params[p.group(1)] = p.group(2)\n",
        "\n",
        "                # Execute tool\n",
        "                if tool_name in self.tools:\n",
        "                    result = self.tools[tool_name][\"func\"](**params)\n",
        "                    print(f\"🔧 Tool Result: {result}\\n\")\n",
        "                    self.history.append(f\"Action: {tool_name}, Result: {result}\")\n",
        "\n",
        "            self.history.append(response)\n",
        "\n",
        "        return \"Max steps reached\"\n",
        "\n",
        "\n",
        "# Define tools\n",
        "def search(query):\n",
        "    responses = {\n",
        "        \"python\": \"Python is a high-level programming language.\",\n",
        "        \"gemini\": \"Gemini is Google's multimodal AI model.\",\n",
        "    }\n",
        "    for key, val in responses.items():\n",
        "        if key in query.lower():\n",
        "            return val\n",
        "    return f\"Found general info about: {query}\"\n",
        "\n",
        "def calc(expression):\n",
        "    try:\n",
        "        return str(eval(expression))\n",
        "    except:\n",
        "        return \"Error in calculation\"\n",
        "\n",
        "def weather(city):\n",
        "    data = {\"london\": \"15°C, Cloudy\", \"paris\": \"17°C, Sunny\"}\n",
        "    return data.get(city.lower(), \"No data\")\n"
      ],
      "metadata": {
        "id": "v3o6EKTdIDFu"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "# Usage\n",
        "agent = ReActAgent()\n",
        "agent.add_tool(\"search\", search, \"Search for information\")\n",
        "agent.add_tool(\"calc\", calc, \"Calculate math expressions\")\n",
        "agent.add_tool(\"weather\", weather, \"Get weather for a city\")\n",
        "\n",
        "# Run examples\n",
        "result = agent.run(\"What is 25 * 4 + 10?\")\n",
        "print(f\"✅ Final: {result}\\n\")\n",
        "\n",
        "result = agent.run(\"Search about Python and tell me what it is\")\n",
        "print(f\"✅ Final: {result}\")"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 488
        },
        "id": "-D0RnDjtIMEo",
        "outputId": "f2e332f6-4005-4654-b19c-d3d97050aa64"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "\n",
            "🎯 Query: What is 25 * 4 + 10?\n",
            "\n",
            "Step 1:\n",
            "Thought:I need to calculate the result of the given expression.\n",
            "Action: calc(expression=\"25 * 4 + 10\")\n",
            "\n",
            "\n",
            "🔧 Tool Result: 110\n",
            "\n",
            "Step 2:\n",
            "Thought:The expression has already been calculated in the history.\n",
            "Final Answer: 110\n",
            "\n",
            "\n",
            "✅ Final: 110\n",
            "\n",
            "\n",
            "🎯 Query: Search about Python and tell me what it is\n",
            "\n",
            "Step 1:\n",
            "Thought:I have already calculated the result of the mathematical expression using the calculator tool. Now I should provide the final answer, which is the result I obtained.\n",
            "Final Answer: 110\n",
            "\n",
            "\n",
            "✅ Final: 110\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "OouVBHtFJNmi"
      },
      "execution_count": null,
      "outputs": []
    }
  ]
}